<template>
  <PageContainer>
    <section class="hero">
      <div class="hero-text">
        <h1>信息工程学讨论区</h1>
        <p>
          与同好一起探讨理论与实践问题，查找精彩帖子，快速加入热门话题。
        </p>
      </div>
      <div class="hero-stats">
        <div>
          <strong>{{ communityStats.totalPosts }}</strong>
          <span>帖子</span>
        </div>
        <div>
          <strong>{{ communityStats.totalReplies }}</strong>
          <span>回复</span>
        </div>
        <div>
          <strong>{{ communityStats.activeAuthors }}</strong>
          <span>活跃用户</span>
        </div>
      </div>
    </section>

    <section class="content-block">
      <form class="search-bar" @submit.prevent="handleSearch">
        <div class="search-input-group">
          <input
            v-model="keyword"
            type="search"
            placeholder="搜索标题、内容或标签关键字"
            class="search-input"
          />
          <button type="submit" class="primary-button">搜索</button>
          <button type="button" class="plain-button" @click="resetSearch" :disabled="!keyword">
            重置
          </button>
        </div>
        <p class="search-helper">支持模糊搜索，输入标签或关键词快速定位相关讨论。</p>
      </form>
    </section>

    <section class="forum-layout">
      <div class="main-column">
        <AsyncState
          :loading="postsLoading"
          :error="postsError"
          :isEmpty="!postCards.length"
          emptyMessage="暂无帖子，欢迎成为第一位分享者！"
          :retry="handleSearch"
        >
          <div class="post-list">
            <InfoCard
              v-for="post in postCards"
              :key="post.id"
              :title="post.title"
              :description="post.excerpt"
              :meta="post.meta"
              :tags="post.tags"
              :to="`/forum/${post.id}`"
              clickable
            />
          </div>
        </AsyncState>
      </div>
      <aside class="sidebar">
        <div class="sidebar-card">
          <h3>热门标签</h3>
          <div v-if="trendingTags.length" class="tag-cloud">
            <button
              v-for="tagName in trendingTags"
              :key="tagName"
              type="button"
              class="tag-button"
              @click="applyTag(tagName)"
            >
              #{{ tagName }}
            </button>
          </div>
          <p v-else class="sidebar-empty">暂无标签统计</p>
        </div>

        <div class="sidebar-card">
          <h3>社区概览</h3>
          <ul class="stats-list">
            <li>
              <span class="stats-value">{{ communityStats.totalPosts }}</span>
              <span class="stats-label">帖子总数</span>
            </li>
            <li>
              <span class="stats-value">{{ communityStats.totalReplies }}</span>
              <span class="stats-label">回复条数</span>
            </li>
            <li>
              <span class="stats-value">{{ communityStats.activeAuthors }}</span>
              <span class="stats-label">活跃作者</span>
            </li>
            <li>
              <span class="stats-value">{{ communityStats.totalLikes }}</span>
              <span class="stats-label">点赞总计</span>
            </li>
          </ul>
          <p class="sidebar-tip">
            最近更新于：<strong>{{ communityStats.latestPostTime }}</strong>
          </p>
        </div>

        <div class="sidebar-card callout">
          <h3>我要发帖</h3>
          <p>分享你的实践经验或课程疑问，社区成员将及时响应。</p>
          <RouterLink class="submit-link" to="/forum">
            规划中的发帖功能，敬请期待
          </RouterLink>
        </div>
      </aside>
    </section>
  </PageContainer>
</template>

<script setup>
import { computed, onMounted, ref } from 'vue'
import PageContainer from '../components/PageContainer.vue'
import AsyncState from '../components/AsyncState.vue'
import InfoCard from '../components/InfoCard.vue'
import { getPosts } from '../api/client'
import { useAsyncData } from '../composables/useAsyncData'
import { formatDate, truncateText } from '../utils/formatters'

const keyword = ref('')
const basePosts = ref([])

const {
  data: posts,
  loading: postsLoading,
  error: postsError,
  execute: fetchPosts,
} = useAsyncData(getPosts, {
  initialValue: [],
  transform: (data) => data?.items ?? [],
  onSuccess: (items) => {
    if (!keyword.value.trim()) {
      basePosts.value = items
    }
  },
})

onMounted(() => {
  handleSearch()
})

const postCards = computed(() =>
  posts.value.map((post) => {
    const replies = post.replies ?? []
    const latestUpdatedAt = replies.length
      ? formatDate(replies[replies.length - 1].created_at || post.created_at)
      : formatDate(post.created_at)
    return {
      ...post,
      excerpt: truncateText(post.content, 90),
      tags: post.tags ?? [],
      meta: [
        { label: '作者', value: post.author || '匿名用户' },
        { label: '发布时间', value: formatDate(post.created_at) },
        { label: '最近更新', value: latestUpdatedAt },
        { label: '点赞', value: post.likes ?? 0 },
        { label: '回复', value: replies.length },
      ],
    }
  }),
)

const trendingTags = computed(() => {
  const counter = new Map()
  basePosts.value.forEach((post) => {
    ;(post.tags || []).forEach((tagName) => {
      counter.set(tagName, (counter.get(tagName) || 0) + 1)
    })
  })
  return Array.from(counter.entries())
    .sort((a, b) => b[1] - a[1])
    .slice(0, 10)
    .map(([name]) => name)
})

const communityStats = computed(() => {
  const totalPosts = basePosts.value.length
  let totalReplies = 0
  let totalLikes = 0
  const authors = new Set()
  let latest = ''

  basePosts.value.forEach((post) => {
    totalReplies += post.replies?.length ?? 0
    totalLikes += post.likes ?? 0
    if (post.author) {
      authors.add(post.author)
    }
    const postDate = post.created_at
    if (!latest || new Date(postDate) > new Date(latest)) {
      latest = postDate
    }
    post.replies?.forEach((reply) => {
      if (reply.author) {
        authors.add(reply.author)
      }
      if (reply.created_at && new Date(reply.created_at) > new Date(latest)) {
        latest = reply.created_at
      }
    })
  })

  return {
    totalPosts,
    totalReplies,
    totalLikes,
    activeAuthors: authors.size,
    latestPostTime: latest ? formatDate(latest) : '暂无记录',
  }
})

function handleSearch() {
  const query = keyword.value.trim() ? { keyword: keyword.value.trim() } : undefined
  return fetchPosts(query).catch(() => {})
}

function resetSearch() {
  keyword.value = ''
  handleSearch()
}

function applyTag(tagName) {
  keyword.value = tagName
  handleSearch()
}
</script>

<style scoped>
.hero {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  padding: 28px;
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(245, 108, 108, 0.12), rgba(64, 158, 255, 0.12));
  border: 1px solid rgba(64, 158, 255, 0.2);
}

.hero-text {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.hero-text h1 {
  margin: 0;
  font-size: 28px;
  font-weight: 700;
}

.hero-text p {
  margin: 0;
  font-size: 15px;
  color: #303133;
  line-height: 1.8;
}

.hero-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(80px, 1fr));
  gap: 16px;
  background: #fff;
  border-radius: 12px;
  padding: 18px;
  border: 1px solid rgba(64, 158, 255, 0.2);
  text-align: center;
}

.hero-stats strong {
  display: block;
  font-size: 24px;
  color: #1f2d3d;
  font-weight: 700;
}

.hero-stats span {
  font-size: 13px;
  color: #606266;
}

.content-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.search-bar {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.search-input-group {
  display: flex;
  gap: 10px;
}

.search-input {
  flex: 1;
  padding: 10px 14px;
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  font-size: 14px;
}

.search-input:focus {
  border-color: #409eff;
  outline: none;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.15);
}

.primary-button,
.plain-button {
  padding: 10px 16px;
  border-radius: 8px;
  border: none;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.primary-button {
  background: #409eff;
  color: #fff;
}

.primary-button:hover {
  background: #337ecc;
}

.plain-button {
  background: #f4f4f5;
  color: #606266;
}

.plain-button:hover:not(:disabled) {
  background: #e9e9eb;
}

.plain-button:disabled {
  cursor: default;
  opacity: 0.6;
}

.search-helper {
  margin: 0;
  font-size: 13px;
  color: #909399;
}

.forum-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 24px;
}

.post-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 18px;
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.sidebar-card {
  border: 1px solid #ebeef5;
  border-radius: 12px;
  padding: 20px;
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sidebar-card h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tag-button {
  border: none;
  padding: 6px 12px;
  border-radius: 999px;
  background: #ecf5ff;
  color: #409eff;
  font-size: 12px;
  cursor: pointer;
}

.tag-button:hover {
  background: #d9ecff;
}

.sidebar-empty {
  margin: 0;
  color: #909399;
  font-size: 13px;
}

.stats-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.stats-value {
  font-weight: 600;
  font-size: 18px;
}

.stats-label {
  display: block;
  color: #909399;
  font-size: 12px;
}

.sidebar-tip {
  margin: 0;
  font-size: 13px;
  color: #606266;
}

.callout {
  background: linear-gradient(135deg, rgba(64, 158, 255, 0.12), rgba(64, 158, 255, 0.05));
  border-color: rgba(64, 158, 255, 0.3);
}

.submit-link {
  display: inline-block;
  color: #409eff;
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
}

.submit-link:hover {
  text-decoration: underline;
}

@media (max-width: 960px) {
  .hero {
    flex-direction: column;
    align-items: flex-start;
  }

  .hero-stats {
    width: 100%;
  }

  .forum-layout {
    grid-template-columns: 1fr;
  }

  .sidebar {
    order: -1;
  }
}

@media (max-width: 640px) {
  .hero {
    padding: 20px;
  }

  .hero-stats {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .search-input-group {
    flex-direction: column;
    align-items: stretch;
  }

  .post-footer {
    flex-direction: column;
    align-items: flex-start;
  }
}
</style>

